package bibbletex.models;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.security.SecureRandom;
import java.math.BigInteger;
import bibbletex.controllers.CollaborationController;

/**
 * Collaboration class is the model for a collaboration.
 * 
 * It contains the basic attributes plus a list of references.
 * 
 * @author Diego Barrios Romero
 * 
 */
public class Collaboration {

	/**
	 * Unique identifier. This will also work as the primary key in the
	 * database.
	 */
	UUID id;
	String public_id, title, description, creator_name, email;

	List<Reference> references;

	/**
	 * When a collaboration is created, a new random UUID is associated to be
	 * able to identify it and later on, associate it with the references.
	 */
	public Collaboration(RequestCollaboration rc) {
		id = UUID.randomUUID();
		references = new ArrayList<Reference>();
		
		SecureRandom srandom = new SecureRandom();
		public_id = new BigInteger(176, srandom).toString(32);
		// TODO: check that there are no collaboration with that public_id

		setTitle(rc.getTitle());
		setDescription(rc.getDescription());
		setCreator_name(rc.getCreator_name());
		setEmail(rc.getEmail());

		CollaborationController.save(this);
	}
	
	public Collaboration(RequestCollaboration rc, UUID uuid, String public_id) {
		id = uuid;
		references = new ArrayList<Reference>();
		
		this.public_id = new String(public_id);

		setTitle(rc.getTitle());
		setDescription(rc.getDescription());
		setCreator_name(rc.getCreator_name());
		setEmail(rc.getEmail());

		CollaborationController.save(this);
	}

	public Collaboration(UUID id, String public_id) {
		this.id = id;
		this.public_id = new String(public_id);
		references = new ArrayList<Reference>();
	}

	public UUID getId() {
		return id;
	}
	
	public String getPublic_id() {
		return public_id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		if (title != null)
			this.title = new String(title);
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		if (description != null)
			this.description = new String(description);
	}

	public String getCreator_name() {
		return creator_name;
	}

	public void setCreator_name(String creator_name) {
		if (creator_name != null)
			this.creator_name = new String(creator_name);
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		if (email != null)
			this.email = new String(email);
	}
	
	public List<Reference> getAllReferences() {
		return references;
	}

	public List<Reference> getReferences() {
		List<Reference> refs = new ArrayList<Reference>();
		for (Reference r : references)
			if (!r.is_suggestion())
				refs.add(r);
		
		return refs;
	}
	
	public List<Reference> getSuggestions() {
		List<Reference> suggs = new ArrayList<Reference>();
		for (Reference r : references)
			if (r.is_suggestion())
				suggs.add(r);
		
		return suggs;
	}

	public void addReference(Reference r) {
		if (r == null)
			System.err.println("addReference: r is null!");
		if (references.contains(r))
			references.remove(r);

		references.add(r);
		
		CollaborationController.addReference(this, r);
	}

	public void deleteReference(String id) {
			references.remove(new Reference(UUID.fromString(id)));
		
		CollaborationController.deleteReference(this, id);
	}
	
	public void deleteReference(Reference r) {
		references.remove(r);
		
		CollaborationController.deleteReference(this, r.getId().toString());
	}

	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof Collaboration) {
			Collaboration other = (Collaboration) obj;
			// By definition, the UUID are uniques so we only need to
			// compare the ID
			return (id.equals(other.id));
		} else {
			return false;
		}
	}

	/* CLASS METHODS */
	/**
	 * This method determines whether a given ID is private (modification will be allowed) 
	 * or public (only suggestion of references will be allowed)
	 * @param id ID parameter
	 * @return private => true, public => false
	 */
	public static boolean id_is_private(String id) {
		// In the way we create the IDs, only UUID have hashes.
		return (id.charAt(8) == '-');
	}

}
